/**
 * FFmpeg 函数库
 * 1. avcodec: 编解码库
 * 2. avdevice: 输入输出设备库
 * 3. avformat：文件封装格式操作库
 * 4. swsscale: 视频像素格式转换库
 * 5. swresample: 音频采样数据库
 * 6. avfilter: 滤镜特效库
 * 7. avutil: 常用工具库
 * 8. postproc: 宏文件库
 */

#include <iostream>

extern "C" {
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
}

// void PrintConfiguration()
// {
//     // 依赖 libavcodec/avcodec.h
//     std::cout << "avcodec_configuration:\n" << avcodec_configuration() << std::endl;
// }

int OpenLocalFile(const char *path) {
    // 1. 注册所有编解码器
    av_register_all();

    // I/O格式上下文
    AVFormatContext *pFormatCtx = avformat_alloc_context();

    // 2. 打开输入流并读取文件头，还没开启解码器
    int ret = avformat_open_input(&pFormatCtx, path, NULL, NULL);
    if (ret < 0) {
        std::cout << "无法开启输入流" << std::endl;
        return -1;
    }

    // 3. 寻找解码器信息，如果开启了网络流，这一步不需要
    ret = avformat_find_stream_info(pFormatCtx, NULL);
    if (ret < 0) {
        std::cout << "无法寻找解码器信息" << std::endl;
        return -1;
    }

    int duration = pFormatCtx->duration;
    int mbittime = duration / AV_TIME_BASE;
    int hours = mbittime / 3600;
    int minutes = (mbittime - hours * 3600) / 60;
    int seconds = mbittime - hours * 3600 - minutes * 60;

    std::cout << "视频时长:" << hours << ":" << minutes << ":" << seconds << std::endl;

    std::cout << "\n打印文件信息" << std::endl;
    av_dump_format(pFormatCtx, NULL, path, 0);
}

int OpenNetwork(const char *path) {
    // 1. 注册所有编解码器
    av_register_all();

    // I/O格式上下文
    AVFormatContext *pFormatCtx = avformat_alloc_context();

    // 打开网络流需要初始化
    avformat_network_init();

    // 打开网络流需要进行设置
    AVDictionary *options = NULL;
    av_dict_set(&options, "rtmp_transport", "tcp", 0);
    av_dict_set(&options, "rtmp_live", "1", 0);
    av_dict_set(&options, "stimeout", "5000000", 0); // 5秒的连接超时
    av_dict_set(&options, "buffer_size", "65536", 0); // 设置缓冲区大小为64KB
    av_dict_set(&options, "max_delay", "5000000", 0); // 设置最大延迟为5秒

    // 2. 打开输入流并读取文件头，还没开启解码器
    int ret = avformat_open_input(&pFormatCtx, path, NULL, &options);
    if (ret < 0) {
        std::cout << "无法开启输入流" << std::endl;
        return -1;
    }

    int duration = pFormatCtx->duration;
    int mbittime = duration / AV_TIME_BASE;
    int hours = mbittime / 3600;
    int minutes = (mbittime - hours * 3600) / 60;
    int seconds = mbittime - hours * 3600 - minutes * 60;

    std::cout << "视频时长:" << hours << ":" << minutes << ":" << seconds << std::endl;

    std::cout << "\n打印文件信息" << std::endl;
    av_dump_format(pFormatCtx, NULL, path, 0);
}

int main()
{
    return OpenLocalFile("../../1.flv");
}